import os

currdir = os.path.dirname(os.path.abspath(__file__))
cfg = os.path.join(currdir, 'metrics.cfg')
rppath = os.path.normpath(os.path.join(currdir, '../parser/repoparsed'))
sppath = os.path.normpath(os.path.join(currdir, '../parser/srcparsed'))
rdpath = os.path.join(currdir, 'repodata')
sdpath = os.path.join(currdir, 'srcdata')
hpath = os.path.join(currdir, 'histograms')

# Remove old files
os.system('rm ' + rdpath + '/*')
os.system('rm ' + sdpath + '/*')
os.system('rm ' + hpath + '/*')

rfiles = os.popen("find " + rppath + " -name '*.parsed'").read().splitlines()
sfiles = os.popen("find " + sppath + " -name '*.parsed'").read().splitlines()

metrics = open(cfg, 'r').read().split('\n')

# Form stats dictionary for repository and Go source files

def process(files):
  stats = {}
  print 'processing ' + str(len(files)) + ' files'
  for f in files:
    # Some stats need to be initialized to 0 to avoid undefined values in expressions
    # Others may need to be set to 1 to avoid division by 0
    fstats = {'FuncDecl.Recv': [0]}
    r = open(f, 'r')
    lines = r.read().splitlines()
    r.close()
    if 'expected' in lines[0]:
      # Not legal Go file
      print f + ' not successfully parsed'
      continue
    for line in lines:
      line = line.strip()
      if line.startswith('#'):
        # Comment
        continue
      parts = line.split(': ')
      key = parts[0]
      val = 1.0
      if ': ' in line:
        try:
          val = float(parts[1])
        except:
          continue
      # Can't use '.' in dictionary key; interpreted as accessing property
      key = key.replace('.', '_')
      if key in fstats:
        fstats[key] += val
      else:
        fstats[key] = val
    #print fstats
    for metric in metrics:
      if metric == '' or metric.startswith('#'):
        continue
      try:
        val = eval(metric.replace('.', '_'), {}, fstats)
      except:
        # Not a 'per' metric
        if '/' not in metric:
          val = 0
        else:
          #print 'failed evaluating metric ' + metric + ' in ' + f
          continue
      if metric in stats:
        stats[metric].append(val)
      else:
        stats[metric] = [val]
  return stats

repostats = process(rfiles)
srcstats = process(sfiles)

# Output stats dictionary to data files

def output(stats, outpath):
  for k in stats:
    # Perhaps not the best naming scheme considering all the problem characters
    name = k.replace('/', '_per_')
    name = name.replace('.', '_')+'.txt'
    name = name.replace('+', '_plus_')
    path = os.path.join(outpath, name)
    out = open(path, 'w')
    for val in stats[k]:
      if val - int(val) < 0.001:
        out.write(str(int(val)) + '\n')
        continue
      out.write('%.3f\n' % val)
    out.close()

output(repostats, rdpath)
output(srcstats, sdpath)

# Call histogram script on data files
# hist.py takes care of Go source histograms at same time
cmd = "find " + rdpath + " -name '*.txt'"
datafiles = os.popen(cmd).read().splitlines()
for df in datafiles:
  cmd = " ".join(['python', 'hist.py', df.replace('(', r'\(').replace(')', r'\)'), hpath, sdpath])
  os.popen(cmd)
